import {Injectable} from '@angular/core';
import {
  Http, Response, RequestOptions, ConnectionBackend, RequestOptionsArgs, Headers,
} from '@angular/http';
import {Observable} from "rxjs";
import {EventsService} from "@core/events/events.service";
import {AuthService} from "@shared/service/auth/auth.service";
import {CLIENT_TYPE} from "@core/globals/globals.service";
@Injectable()
export class HttpIntercept extends Http {

  public userid: string;
  public token: string;
  public HAS_LOGGED_IN = false;
  private requests = 0;

  constructor(
    public backend: ConnectionBackend,
    public defaultOptions: RequestOptions,
    public auth: AuthService,
    public events: EventsService
  ) {
    super(backend, defaultOptions);
    this.getUserData();
  }


  getUserData() {
    // this.userid = 'hhly92799';
    // this.token = 'fdd9cce105ee43389974adcb39d0d470';
    // this.HAS_LOGGED_IN = true;
    const auth = this.auth;
    this.userid = auth.getUserId();
    this.token = auth.getToken();
    this.HAS_LOGGED_IN = !!auth.hasLoggedIn();
  }

  _setCustomHeaders(options?: RequestOptionsArgs): RequestOptionsArgs {


    if (!options) {
      options = new RequestOptions({});
    }
    if (!options.headers) {
      options.headers = new Headers();
    }

    const hasLoggedIn = this.auth.hasLoggedIn(),
      headers = options.headers;
    if (hasLoggedIn === 'false' || hasLoggedIn == null) {
      headers.set("X-SNS-UserId", '');
      headers.set("X-SNS-Timestamp", '');
      headers.set("X-SNS-Signature", '');
      headers.set("X-SNS-ClientType", CLIENT_TYPE);
    } else {
      this.getUserData();
      const timestamp = new Date().getTime();
      const signature = this.auth.buildSignature(this.userid, this.token, timestamp);
      headers.set("X-SNS-UserId", this.userid);
      headers.set("X-SNS-Timestamp", timestamp.toString());
      headers.set("X-SNS-Signature", signature);
      headers.set("X-SNS-ClientType", CLIENT_TYPE);
    }


    return options;
  }

  get(url: string, options ?: RequestOptionsArgs): Observable<Response> {
    options = this._setCustomHeaders(options);
    this.requests++;
    return Observable.create((observer) => {

      super.get(url, options).do(() => {
        this.events.publish('request:start');
      }).subscribe(res => {
        observer.next(res);
        this.requests--;
        this.auth.urlHandler(res, url);
        observer.complete();
        if (this.requests === 0) {
          this.events.publish('request:finished');
        }
      }, err => {
        this.requests--;
        this.events.publish('request:finished');
        observer.error(err);
      });
    });
  }

  post(url: string, body: any, options?: RequestOptionsArgs): Observable<Response> {
    options = this._setCustomHeaders(options);

    return Observable.create((observer) => {
      super.post(url, body, options).subscribe(res => {
        observer.next(res);
        this.auth.urlHandler(res, url);
      }, err => {
        observer.error(err);
      });
    });
  }

  put(url: string, body: any, options?: RequestOptionsArgs): Observable<Response> {
    options = this._setCustomHeaders(options);

    return Observable.create((observer) => {
      super.put(url, body, options).subscribe(res => {
        observer.next(res);
        this.auth.urlHandler(res, url);
      }, err => {
        observer.error(err);
      });
    });
  }

  delete(url: string, options ?: RequestOptionsArgs): Observable<Response> {
    options = this._setCustomHeaders(options);

    return Observable.create((observer) => {
      super.delete(url, options).subscribe(res => {
        observer.next(res);
        this.auth.urlHandler(res, url);
      }, err => {
        observer.error(err);
      });
    });
  }

  patch(url: string, body: any, options?: RequestOptionsArgs): Observable<Response> {
    options = this._setCustomHeaders(options);

    return Observable.create((observer) => {
      super.patch(url, body, options).subscribe(res => {
        observer.next(res);
        this.auth.urlHandler(res, url);
      }, err => {
        observer.error(err);
      });
    });
  }


  head(url: string, options ?: RequestOptionsArgs): Observable<Response> {
    options = this._setCustomHeaders(options);

    return Observable.create((observer) => {
      super.head(url, options).subscribe(res => {
        observer.next(res);
        this.auth.urlHandler(res, url);
      }, err => {
        observer.error(err);
      });
    });
  }


  options(url: string, options ?: RequestOptionsArgs): Observable<Response> {
    options = this._setCustomHeaders(options);

    return Observable.create((observer) => {
      super.options(url, options).subscribe(res => {
        observer.next(res);
        this.auth.urlHandler(res, url);
      }, err => {
        observer.error(err);
      });
    });
  }

}
